[id].vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <template>
  2. <div class="flex h-screen">
  3. <div
  4. class="w-80 bg-white py-4 relative border-l border-gray-100 flex flex-col"
  5. >
  6. <workflow-edit-block
  7. v-if="state.isEditBlock"
  8. :data="state.blockData"
  9. @update="updateBlockData"
  10. @close="(state.isEditBlock = false), (state.blockData = {})"
  11. />
  12. <workflow-details-card
  13. v-else
  14. :workflow="workflow"
  15. @save="saveWorkflow"
  16. @execute="executeWorkflow"
  17. @update="updateWorkflow"
  18. />
  19. </div>
  20. <workflow-builder
  21. class="flex-1"
  22. :data="workflow.drawflow"
  23. @load="editor = $event"
  24. @addBlock="addBlock"
  25. @deleteBlock="deleteBlock"
  26. @export="updateWorkflow({ drawflow: $event })"
  27. />
  28. </div>
  29. </template>
  30. <script setup>
  31. import {
  32. computed,
  33. reactive,
  34. shallowRef,
  35. provide,
  36. onMounted,
  37. onUnmounted,
  38. } from 'vue';
  39. import { useRoute, useRouter } from 'vue-router';
  40. import emitter from 'tiny-emitter/instance';
  41. import Task from '@/models/task';
  42. import Workflow from '@/models/workflow';
  43. import { debounce } from '@/utils/helper';
  44. import WorkflowBuilder from '@/components/newtab/workflow/WorkflowBuilder.vue';
  45. import WorkflowEditBlock from '@/components/newtab/workflow/WorkflowEditBlock.vue';
  46. import WorkflowDetailsCard from '@/components/newtab/workflow/WorkflowDetailsCard.vue';
  47. const route = useRoute();
  48. const router = useRouter();
  49. const workflowId = route.params.id;
  50. const editor = shallowRef(null);
  51. const state = reactive({
  52. isEditBlock: false,
  53. blockData: {},
  54. });
  55. const workflow = computed(() => Workflow.find(workflowId) || {});
  56. const updateBlockData = debounce((data) => {
  57. state.blockData.data = data;
  58. editor.value.updateNodeDataFromId(state.blockData.blockId, data);
  59. const inputEl = document.querySelector(
  60. `#node-${state.blockData.blockId} input.trigger`
  61. );
  62. if (inputEl) inputEl.dispatchEvent(new Event('change'));
  63. }, 250);
  64. function addBlock(data) {
  65. Task.insert({
  66. data: { ...data, workflowId },
  67. });
  68. }
  69. function deleteBlock(id) {
  70. if (state.isEditBlock && state.blockData.blockId === id) {
  71. state.isEditBlock = false;
  72. state.blockData = {};
  73. }
  74. }
  75. function updateWorkflow(data) {
  76. Workflow.update({
  77. where: workflowId,
  78. data,
  79. });
  80. }
  81. function saveWorkflow() {
  82. const data = editor.value.export();
  83. console.log(data);
  84. updateWorkflow({ drawflow: JSON.stringify(data) });
  85. }
  86. function editBlock(data) {
  87. state.isEditBlock = true;
  88. state.blockData = data;
  89. }
  90. function executeWorkflow() {
  91. console.log(editor.value);
  92. }
  93. provide('workflow', {
  94. data: workflow,
  95. updateWorkflow,
  96. });
  97. onMounted(() => {
  98. const isWorkflowExists = Workflow.query().where('id', workflowId).exists();
  99. if (!isWorkflowExists) {
  100. router.push('/workflows');
  101. }
  102. emitter.on('editor:edit-block', editBlock);
  103. });
  104. onUnmounted(() => {
  105. emitter.off('editor:edit-block', editBlock);
  106. });
  107. </script>
  108. <style>
  109. .ghost-task {
  110. height: 40px;
  111. @apply bg-box-transparent;
  112. }
  113. .ghost-task:not(.workflow-task) * {
  114. display: none;
  115. }
  116. </style>